//
//  MKUIAlertView.m
//  MKUI
//
//  Created by 苏尚进 on 2023/11/2.
//  Copyright © 2023 moon. All rights reserved.
//

#import "MKUIAlertView.h"
#import "MKUIListView.h"
#import "UIColor+MKUI.h"
#import "UIScrollView+MKUI.h"
#import "UIView+MKUI.h"
#import "MKUIPreCompile.h"
#import "NSObject+MKUI.h"

#ifdef DEBUG
//#define DEBUG_MKUIAlertView 1
#endif

//由于present viewcontroller同时只能有一个，因此对present的alert同时队列管理，保证所有的alert都能有机会被展示
@interface MKUIAlertTaskManager : NSObject
MKAS_SINGLETON(MKUIAlertTaskManager)
- (void)presentAlertController:(MKUIAlertController *)alert inWindow:(UIWindow *)window animated:(BOOL)animated completion:(void (^ __nullable)(void))completion;
- (void)removeTask:(MKUIAlertController *)alert;
@end

@interface _MKUIAlertActionsListView : MKUIListView
@property(nonatomic,strong) MKUIListViewSeparatorView *topBorder;
@end
@implementation _MKUIAlertActionsListView
- (id)initWithFrame:(CGRect)frame{
    if(self=[super initWithFrame:frame]){
    }
    return self;
}
- (void)setTopBorder:(MKUIListViewSeparatorView *)topBorder{
    if(_topBorder==topBorder)return;
    if(_topBorder){
        [_topBorder removeFromSuperview];
    }
    _topBorder = topBorder;
    if(_topBorder){
        [self addSubview:_topBorder];
        [self reloadTopBorder];
    }
}
- (void)setContentOffset:(CGPoint)contentOffset{
    [super setContentOffset:contentOffset];
    [self reloadTopBorder];
}
- (void)reloadTopBorder{
    if(!self.topBorder)return;
    MKCGAxis Y = MKCGAxisY;
    CGRect bounds = self.bounds;
    CGRect f1 = bounds;
    f1.size.height = self.topBorder.separatorSize;
    MKCGRectSetMin(&f1, Y, MKCGPointGetValue(self.contentOffset, Y));
    self.topBorder.frame = f1;
    if(!self.topBorder.superview){
        [self addSubview:self.topBorder];
    }else{
        [self bringSubviewToFront:self.topBorder];
    }
}
@end

@implementation MKUIAutoLayoutViewContainer
- (void)didMoveToSuperview{
    [super didMoveToSuperview];
    self.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
}
- (void)layoutSubviews{
    [super layoutSubviews];
    if(self.whenLayoutSubviews){
        self.whenLayoutSubviews(self);
    }
}
@end

@interface _MKUIAlertGroupBackgroundView : UIView
@property(nonatomic,strong) UIVisualEffectView *backgroundEffectView;//半透明效果

@end
@implementation _MKUIAlertGroupBackgroundView
- (id)initWithFrame:(CGRect)frame{
    if(self=[super initWithFrame:frame]){
        self.backgroundColor = UIColor.mk_alertBackgroundColor;[UIColor mk_colorWithLight:UIColor.whiteColor];
        self.backgroundEffectView = [[UIVisualEffectView alloc] init];
        [self addSubview:self.backgroundEffectView];
        [self _MKUICustomTabBar_doTraitCollection];
    }
    return self;
}
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection{
    [super traitCollectionDidChange:previousTraitCollection];
    [self _MKUICustomTabBar_doTraitCollection];
}
- (void)layoutSubviews{
    [super layoutSubviews];
    self.backgroundEffectView.frame = self.bounds;
}
- (void)_MKUICustomTabBar_doTraitCollection{
    if (@available(iOS 12.0, *)) {
        if(self.traitCollection.userInterfaceStyle==UIUserInterfaceStyleDark){
            self.backgroundEffectView.effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
        }else{
            self.backgroundEffectView.effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleExtraLight];
        }
    }else{
        self.backgroundEffectView.effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleExtraLight];
    }
}
@end


@interface MKUIAlertAction()
@property(nonatomic,weak) __kindof MKUIAlertActionView *actionCell;
@property(nonatomic,weak) __kindof MKUIAlertView *alertView;
@end

@implementation MKUIAlertAction
#ifdef DEBUG_MKUIAlertView
- (void)dealloc{
    NSLog(@"dealloc:MKUIAlertAction:%@",self);
}
#endif
- (id)copyWithZone:(NSZone *)zone{
    MKUIAlertAction *obj = [self.class allocWithZone:zone];
    obj.title = self.title;
    obj.style = self.style;
    obj.enabled = self.isEnabled;
    obj.handler = [self.handler copy];
    obj.willDisplayAction = [self.willDisplayAction copy];
    obj.cellClass = self.cellClass;
    obj.shouldDismissWhenActionHandle = self.shouldDismissWhenActionHandle;
    return obj;
}
+ (instancetype)actionWithTitle:(nullable NSString *)title style:(MKUIAlertActionStyle)style handler:(void (^ _Nullable)(__kindof MKUIAlertAction *action))handler{
    MKUIAlertAction *obj = [[self alloc] init];
    obj.title = title;
    obj.style = style;
    obj.handler = handler;
    return obj;
}
- (id)init{
    if(self=[super init]){
        self.enabled = YES;
        self.shouldDismissWhenActionHandle = YES;
    }
    return self;
}
- (void)setTitle:(NSString * _Nullable)title{
    if(_title==title||[_title isEqualToString:title])return;
    _title = title;
    [self reloadActionCell];
}
- (void)setStyle:(MKUIAlertActionStyle)style{
    if(_style==style)return;
    _style = style;
    [self reloadActionCell];
}
- (void)setEnabled:(BOOL)enabled{
    if(_enabled==enabled)return;
    _enabled = enabled;
    [self reloadActionCell];
}
- (void)setCellClass:(Class)cellClass{
    if(_cellClass==cellClass)return;
    _cellClass = cellClass;
    [self reloadActionCell];
}
- (void)reloadActionCell{
    if(!self.actionCell)return;
    [self.actionCell reloadAction];
}
- (MKUIAlertController *)alertController{
    UIViewController *vc = self.alertView.mk_viewControllerOfFirst;
    if([vc isKindOfClass:MKUIAlertController.class]){
        return (MKUIAlertController *)vc;
    }
    return nil;
}
@end

@interface MKUIAlertActionView(){
    BOOL _needReloadAction;
}
@property(nonatomic,strong) UILabel *titleLabel;
@end
@implementation MKUIAlertActionView
#ifdef DEBUG_MKUIAlertView
- (void)dealloc{
    NSLog(@"dealloc:MKUIAlertActionView:%@",self);
}
- (void)setFrame:(CGRect)frame{
    [super setFrame:frame];
}
#endif
- (id)initWithFrame:(CGRect)frame{
    if(self=[super initWithFrame:frame]){
        self.selectedBackgroundColor = UIColor.mk_actionCellSelectedColor;
        
        self.backgroundColor = UIColor.clearColor;
        self.titleLabel = [[UILabel alloc] init];
        self.titleLabel.adjustsFontSizeToFitWidth = YES;
        self.titleLabel.minimumScaleFactor = 12.0/17.0;
        self.titleLabel.numberOfLines = 1;
        self.titleLabel.textAlignment = NSTextAlignmentCenter;
        [self.contentView addSubview:self.titleLabel];
        self.contentInsets = UIEdgeInsetsMake(0, 12, 0, 12);
    }
    return self;
}
- (void)setContentInsets:(UIEdgeInsets)contentInsets{
    if(UIEdgeInsetsEqualToEdgeInsets(contentInsets, _contentInsets))return;
    _contentInsets = contentInsets;
    [self setNeedsLayout];
}
- (void)layoutContentView{
    [super layoutContentView];
    [self reloadActionIfNeeded];
    CGRect bounds = self.contentView.bounds;
    CGRect f1 = UIEdgeInsetsInsetRect(bounds, self.contentInsets);
    self.titleLabel.frame = f1;
}
- (CGSize)sizeThatFits:(CGSize)size{
    [self reloadActionIfNeeded];
    return [super sizeThatFits:size];
}
- (void)setAction:(MKUIAlertAction *)action{
    _action = action;
    action.actionCell = self;
    [self setNeedReloadAction];
}
- (void)setNeedReloadAction{
    _needReloadAction = YES;
}
- (void)reloadActionIfNeeded{
    if(!_needReloadAction)return;
    _needReloadAction = NO;
    [self reloadAction];
}
- (UIFont *)titleFont{
    UIFont *font = nil;
    CGFloat fontSize = self.alertViewStyle==MKUIAlertViewStyleAlert?17:20;
    switch (self.action.style) {
        case MKUIAlertActionStyleDefault:
            font = [UIFont systemFontOfSize:fontSize];
            break;
        case MKUIAlertActionStyleCancel:
            font = [UIFont boldSystemFontOfSize:fontSize];
            break;
        case MKUIAlertActionStyleDestructive:
            font = [UIFont systemFontOfSize:fontSize];
            break;
        default:
            font = [UIFont systemFontOfSize:fontSize];
            break;
    }
    return font;
}
- (UIColor *)titleColor{
    UIColor *color = nil;
    if(!self.action.isEnabled){
        color = UIColor.mk_disableActionColor;
    }else{
        switch (self.action.style) {
            case MKUIAlertActionStyleDefault:
                color = UIColor.mk_defaultActionStyleColor;
                break;
            case MKUIAlertActionStyleCancel:
                color = UIColor.mk_cancelStyleActionColor;
                break;
            case MKUIAlertActionStyleDestructive:
                color = UIColor.mk_destructiveActionStyleColor;
                break;
            default:
                color = UIColor.mk_defaultActionStyleColor;
                break;
        }
    }
    return color;
}
- (void)reloadAction{
    self.titleLabel.text = self.action.title;
    self.enableSelection = self.action.isEnabled;
    self.titleLabel.font = self.titleFont;
    self.titleLabel.textColor = self.titleColor;
}
- (void)handleAction{
    MKUIAlertView *alert = [self mk_firstSuperViewWithClass:MKUIAlertView.class];
    [alert handleAction:self.action];
}
- (void)listView:(MKUIListView *)listView willDisplayAtIndexPath:(NSIndexPath *)indexPath{
    if(self.action.willDisplayAction){
        self.action.willDisplayAction(self.action);
    }
}
@end

@interface MKUIAlertView()<MKUIListViewDelegate>{
    NSMutableArray<MKUIAlertAction *> *_actions;
    NSMutableArray<MKUIAlertAction *> *_cancelActions;
    NSMutableArray<MKUIAlertAction *> *_normalActions;
    MKUIListView *_contentView;
    MKUIAutoLayoutViewContainer *_maskView;
    BOOL _isSizeFiting;
    BOOL _needReloadData;
    _MKUIAlertActionsListView *_actionContentView;
}
@property(nonatomic,strong) MKUIListView *contentView;//所有视图的容器
@property(nonatomic,strong) MKUIListView *headContentView;//头部内容区域，不可滚动
@property(nonatomic,strong) MKUIListView *bodyContentView;//主体内容区域，可滚动
@property(nonatomic,strong) MKUIListView *footContentView;//尾部内容区域，不可滚动
@property(nonatomic,strong) MKUIListView *actionContentView;//位于底部按钮区域，可滚动
@property(nonatomic,strong) MKUIAlertViewTextCellView *titleView;
@property(nonatomic,strong) MKUIAlertViewTextCellView *messageView;
@property(nonatomic,strong) UIView *maskView;
@property(nonatomic,strong) UITapGestureRecognizer *maskViewTapGesture;
@property(nonatomic,strong) UITapGestureRecognizer *keyboardTapGesture;
@property(nonatomic,strong) NSNotification *keyboardChangeNotification;
@end

@implementation MKUIAlertView
#ifdef DEBUG_MKUIAlertView
- (void)dealloc{
    NSLog(@"dealloc:MKUIAlertView:%@",self);
}
#endif
+ (instancetype)alertViewWithTitle:(nullable NSString *)title message:(nullable NSString *)message preferredStyle:(MKUIAlertViewStyle)preferredStyle{
    MKUIAlertView *alertView = [[self alloc] init];
    alertView.title = title;
    alertView.message = message;
    alertView.preferredStyle = preferredStyle;
    return alertView;
}
- (id)initWithFrame:(CGRect)frame{
    if(self=[super initWithFrame:frame]){
        _showMaskView = YES;
        _alertActionsCountForHorizontal = 2;
        _actionCellClass = MKUIAlertActionView.class;
        _actions = [[NSMutableArray alloc] init];
        _cancelActions = [[NSMutableArray alloc] init];
        _normalActions = [[NSMutableArray alloc] init];
        _contentView = [[MKUIListView alloc] initWithFrame:frame style:(MKUIListViewStyleInsetGrouped)];
        _contentView.backgroundColor = UIColor.clearColor;
        _contentView.groupBackgroundColor = nil;
        _contentView.groupBackgroundViewClass = _MKUIAlertGroupBackgroundView.class;
        _contentView.scrollEnabled = NO;
        _contentView.showsVerticalScrollIndicator = NO;
        _contentView.showsHorizontalScrollIndicator = NO;
        _contentView.clipsToBounds = YES;
        _contentView.sectionInteritemSpacing = 8;
        _contentView.groupCornerRadius = 12;
        _contentView.groupInsets = UIEdgeInsetsMake(0, 8, 0, 8);
        _contentView.separatorStyle = MKUIListViewCellSeparatorStyleSingleLine;
        _contentView.delegate = self;
        [self addSubview:_contentView];
        //
        self.headContentView = [[MKUIListView alloc] initWithFrame:CGRectZero style:(MKUIListViewStyleInsetGrouped)];
        self.headContentView.scrollEnabled = NO;
        self.headContentView.backgroundColor = UIColor.clearColor;
        self.headContentView.groupBackgroundColor = UIColor.clearColor;
        self.headContentView.groupCornerRadius = 0;
        self.headContentView.separatorStyle = MKUIListViewCellSeparatorStyleNone;
        self.headContentView.groupInsets = UIEdgeInsetsMake(0, 16, 0, 16);
        self.headContentView.cellInteritemSpacing = 6;
        [self.headContentView addSection];
        //
        self.bodyContentView = [[MKUIListView alloc] initWithFrame:frame style:(MKUIListViewStyleInsetGrouped)];
        self.bodyContentView.backgroundColor = UIColor.clearColor;
        self.bodyContentView.groupBackgroundColor = UIColor.clearColor;
        self.bodyContentView.groupCornerRadius = 0;
        self.bodyContentView.separatorStyle = MKUIListViewCellSeparatorStyleNone;
        self.bodyContentView.groupInsets = UIEdgeInsetsMake(0, 16, 0, 16);
        self.bodyContentView.cellInteritemSpacing = 6;
        [self.bodyContentView addSection];//显示title、message
        
        //
        self.footContentView = [[MKUIListView alloc] initWithFrame:CGRectZero style:(MKUIListViewStyleInsetGrouped)];
        self.footContentView.scrollEnabled = NO;
        self.footContentView.backgroundColor = UIColor.clearColor;
        self.footContentView.groupBackgroundColor = UIColor.clearColor;
        self.footContentView.groupCornerRadius = 0;
        self.footContentView.separatorStyle = MKUIListViewCellSeparatorStyleNone;
        self.footContentView.groupInsets = UIEdgeInsetsMake(0, 16, 0, 16);
        self.footContentView.cellInteritemSpacing = 6;
        [self.footContentView addSection];
        //
        self.actionContentView = [[_MKUIAlertActionsListView alloc] initWithFrame:frame style:(MKUIListViewStyleInsetGrouped)];
        self.actionContentView.backgroundColor = UIColor.clearColor;
        self.actionContentView.groupBackgroundColor = UIColor.clearColor;
        self.actionContentView.groupCornerRadius = 0;
        self.actionContentView.separatorStyle = MKUIListViewCellSeparatorStyleSingleLine;
        self.actionContentView.groupInsets = UIEdgeInsetsZero;
        self.actionContentView.cellInteritemSpacing = 0;
        self.actionContentView.contentInset = UIEdgeInsetsZero;
        
        [self.actionContentView addSection];//actionSection
        self.actionContentView.delegate = self;
        //
        MKUIListViewSeparatorView *separatorViewBetweentTextAndActions = [[MKUIListViewSeparatorView alloc] init];
        separatorViewBetweentTextAndActions.separatorColor = _contentView.separatorColor;
        separatorViewBetweentTextAndActions.separatorSize = _contentView.separatorSize;
        _separatorViewBetweentTextAndActions = separatorViewBetweentTextAndActions;
        
        //
        [_contentView addSection];//显示headContentView，bodyContentView，footContentView，actionContentView
        [_contentView setSeparatorStyle:(MKUIListViewCellSeparatorStyleNone) forSection:0];
        [_contentView setCellInteritemSpacing:10 forSection:0];
        [_contentView addItem:self.headContentView];
        [_contentView addItem:self.bodyContentView];
        [_contentView addItem:self.footContentView];
        [_contentView addItem:self.actionContentView];
        //
        MKUIAutoLayoutViewContainer *maskView = [[MKUIAutoLayoutViewContainer alloc] init];
        maskView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.2];
        @MK_WEAKIFY(self);
        maskView.whenLayoutSubviews = ^(__kindof UIView *maskView) {
            @MK_NORMALIZE(self);
            [self _layoutSelfInContainerView:self.superview];
            [self layoutMaskViewInContainerView:self.superview];
        };
        _maskView = maskView;
        self.maskViewTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(__onMaskViewDidTap:)];
        [_maskView addGestureRecognizer:self.maskViewTapGesture];
        //
        self.autoAdjustContentWhenKeyboardChange = YES;
        self.autoAdjustViewClassWhenKeyboardChange = self.class;
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(__MKUIAlertView_onKeyboardShow:) name:UIKeyboardDidShowNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(__MKUIAlertView_onKeyboardChange:) name:UIKeyboardDidChangeFrameNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(__MKUIAlertView_onKeyboardHide:) name:UIKeyboardDidHideNotification object:nil];
        self.keyboardTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(__MKUIAlertView_onKeyboardTap:)];
        self.keyboardTapGesture.enabled = NO;
    }
    return self;
}
- (MKUIListView *)actionContentView{
    return _actionContentView;
}
- (void)layoutSubviews{
    [super layoutSubviews];
    CGRect bounds = self.bounds;
    _contentView.frame = bounds;
    [self reloadDataIfNeeded];
    
    [self.headContentView layoutIfNeeded];
    [self.bodyContentView layoutIfNeeded];
    [self.actionContentView layoutIfNeeded];
    [self.footContentView layoutIfNeeded];
    [self.bodyContentView mk_autoBounces];
    [self.actionContentView mk_autoBounces];
}
- (CGFloat)widthThatFits:(CGSize)size{
    CGFloat width = 0;
    if(self.preferredStyle==MKUIAlertViewStyleAlert){
        //alert时，宽度固定为270
        width = 270;
    }else{
        width = 275;
    }
    return width;
}
- (CGSize)sizeThatFits:(CGSize)size{
    [self reloadDataIfNeeded];
    CGSize s = size;
    CGFloat width = [self widthThatFits:size];
    if(self.preferredStyle==MKUIAlertViewStyleAlert){
        //alert时，宽度固定为270
        size.width = width;
        s = [_contentView sizeThatFits:size];
        s.width = width;
    }else{
        //actionSheet时，竖屏下，宽度固定为屏幕宽度；横屏固定为275
        CGRect mainBounds = UIScreen.mainScreen.bounds;
        BOOL isHor = mainBounds.size.width>mainBounds.size.height;
        if(isHor){//横屏时，宽度固定为275
            size.width = width;
            s = [_contentView sizeThatFits:size];
            s.width = width;
        }else{//竖屏时，宽度为容器尺寸
            s = [_contentView sizeThatFits:size];
            s.width = size.width;
        }
    }
    s.height = MIN(s.height,size.height);
    return s;
}
- (UIView *)contentView{
    return _contentView;
}
- (UIView *)maskView{
    return _maskView;
}
- (void)setTitle:(NSString *)title{
    if(_title==title||[_title isEqualToString:title])return;
    _title = title;
    self.titleView.text = self.title;
    [self setNeedReloadData];
}
- (MKUIAlertViewTextCellView *)titleView{
    if(_titleView)return _titleView;
    _titleView = [[MKUIAlertViewTextCellView alloc] init];
    return _titleView;
}
- (void)setMessage:(NSString *)message{
    if(_message==message||[_message isEqualToString:message])return;
    _message = message;
    self.messageView.text = self.message;
    [self setNeedReloadData];
}
- (MKUIAlertViewTextCellView *)messageView{
    if(_messageView)return _messageView;
    _messageView = [[MKUIAlertViewTextCellView alloc] init];
    _messageView.textLabel.font = [UIFont systemFontOfSize:13];
    return _messageView;
}
- (void)addAction:(MKUIAlertAction *)action{
    if(!action)return;
    if([_actions containsObject:action])return;
    action.alertView = self;
    [_actions addObject:action];
    [self setNeedReloadData];
}
- (void)setActions:(NSArray<MKUIAlertAction *> *)actions{
    for(MKUIAlertAction *action in _actions){
        action.alertView = nil;
    }
    [_actions removeAllObjects];
    if(actions)[_actions addObjectsFromArray:actions];
    for(MKUIAlertAction *action in _actions){
        action.alertView = self;
    }
    [self setNeedReloadData];
}
- (NSArray<MKUIAlertAction *> *)actions{
    return _actions;
}
- (void)setActionCellClass:(Class)actionCellClass{
    if(_actionCellClass==actionCellClass)return;
    _actionCellClass = actionCellClass;
    [self setNeedReloadData];
}
- (void)setSeparatorViewBetweentTextAndActions:(MKUIListViewSeparatorView *)separatorViewBetweentTextAndActions{
    if(_separatorViewBetweentTextAndActions==separatorViewBetweentTextAndActions)return;
    _separatorViewBetweentTextAndActions = separatorViewBetweentTextAndActions;
    [self reloadActionTopBorder];
}
- (MKUIAlertActionView *)_createActionView:(MKUIAlertAction *)action{
    Class cellClass = action.cellClass?:self.actionCellClass;
    MKUIAlertActionView *actionView = [[cellClass alloc] init];
    actionView.alertViewStyle = self.preferredStyle;
    actionView.action = action;
    return actionView;
}
- (void)setNeedReloadData{
    _needReloadData = YES;
    [self.maskView setNeedsLayout];
    [self setNeedsLayout];
}
- (void)reloadDataIfNeeded{
    if(!_needReloadData)return;
    _needReloadData = NO;
    [self reloadData];
}
- (void)reloadData{
    [self reloadTitleView];
    [self reloadMessageView];
    [self reloadActionContent];
    
    [self reloadContentData];
    
    [self reloadActionTopBorder];
    [self reloadContentSection0Spacing];
    
    [_contentView reloadData];
    [self.bodyContentView reloadData];
    [self.actionContentView reloadData];
}
- (void)reloadTitleView{
    if(self.title){
        self.titleView.textLabel.font = self.preferredStyle==MKUIAlertViewStyleAlert?[UIFont boldSystemFontOfSize:17]:[UIFont boldSystemFontOfSize:13];
        self.titleView.textLabel.textColor = self.preferredStyle==MKUIAlertViewStyleAlert?[UIColor mk_colorWithLight:UIColor.blackColor dark:UIColor.whiteColor]:[UIColor mk_colorWithString:@"#858585"];
        NSIndexPath *path = [self.bodyContentView indexPathForCell:self.titleView];
        if(path){
            [self.bodyContentView reloadItemAtIndexPath:path];
        }else{
            [self.bodyContentView addItem:self.titleView atSectionIndex:0];
        }
    }else{
        [self.bodyContentView deleteItem:self.titleView withAnimation:(MKUIListViewItemAnimationNone)];
    }
}
- (void)reloadMessageView{
    if(self.message){
        self.messageView.textLabel.textColor = self.preferredStyle==MKUIAlertViewStyleAlert?[UIColor mk_colorWithLight:UIColor.blackColor dark:UIColor.whiteColor]:[UIColor mk_colorWithString:@"#858585"];
        NSIndexPath *path = [self.bodyContentView indexPathForCell:self.messageView];
        if(path){
            [self.bodyContentView reloadItemAtIndexPath:path];
        }else{
            [self.bodyContentView addItem:self.messageView atSectionIndex:0];
        }
    }else{
        [self.bodyContentView deleteItem:self.messageView withAnimation:(MKUIListViewItemAnimationNone)];
    }
}
- (void)reloadActionContent{
    [_cancelActions removeAllObjects];
    [_normalActions removeAllObjects];
    
    for(MKUIAlertAction *action in self.actions){
        if(action.style==MKUIAlertActionStyleCancel){
            [_cancelActions addObject:action];
        }else{
            [_normalActions addObject:action];
        }
    }
    NSMutableArray<MKUIAlertAction *> *sortedActions = [[NSMutableArray alloc] initWithCapacity:self.actions.count];
    if(self.preferredStyle==MKUIAlertViewStyleAlert){//
        if(self.actions.count<=self.alertActionsCountForHorizontal){//横向
            [sortedActions addObjectsFromArray:_cancelActions];
            [sortedActions addObjectsFromArray:_normalActions];
        }else{
            [sortedActions addObjectsFromArray:_normalActions];
            [sortedActions addObjectsFromArray:_cancelActions];
        }
    }else{
        [sortedActions addObjectsFromArray:_normalActions];
    }
    
    self.actionContentView.scrollDirection =  (self.preferredStyle==MKUIAlertViewStyleActionSheet||self.actions.count>self.alertActionsCountForHorizontal)?MKUIListViewScrollDirectionVertical:MKUIListViewScrollDirectionHorizontal;
    [self.actionContentView deleteAllSections];
    for(MKUIAlertAction *action in sortedActions){
        MKUIAlertActionView *actionView = [self _createActionView:action];
        [self.actionContentView addItem:actionView];
    }
}
- (void)reloadContentData{
    NSInteger bodySection = 0;
    
    [_contentView deleteItem:self.headContentView withAnimation:(MKUIListViewItemAnimationNone)];
    if(self.headContentView.numberOfItems>0){
        [_contentView addItem:self.headContentView atSectionIndex:bodySection];
    }
    
    [_contentView deleteItem:self.bodyContentView withAnimation:(MKUIListViewItemAnimationNone)];
    if(self.bodyContentView.numberOfItems>0){
        [_contentView addItem:self.bodyContentView atSectionIndex:bodySection];
    }
    
    [_contentView deleteItem:self.footContentView withAnimation:(MKUIListViewItemAnimationNone)];
    if(self.footContentView.numberOfItems>0){
        [_contentView addItem:self.footContentView atSectionIndex:bodySection];
    }
    
    [_contentView deleteItem:self.actionContentView withAnimation:(MKUIListViewItemAnimationNone)];
    if(self.actionContentView.numberOfItems>0){
        [_contentView addItem:self.actionContentView atSectionIndex:bodySection];
    }
    
    NSInteger cancelSection = 1;
    [_contentView deleteSectionViewsAtIndex:cancelSection];
    if(self.preferredStyle==MKUIAlertViewStyleActionSheet){//sheet时，cancel单独一个分组显示
        if(_contentView.numberOfSections<=cancelSection){
            [_contentView addSection];
            cancelSection = _contentView.numberOfSections-1;
        }
        [_contentView setGroupBackgroundColor:[UIColor mk_colorWithLight:UIColor.whiteColor dark:[UIColor mk_colorWithString:@"#2C2C2C"]] forSection:cancelSection];
        for(MKUIAlertAction *action in _cancelActions){
            MKUIAlertActionView *actionView = [self _createActionView:action];
            [_contentView addItem:actionView atSectionIndex:cancelSection];
        }
    }
}
- (void)reloadActionTopBorder{
    NSIndexPath *actionPath = [_contentView indexPathForCell:self.actionContentView];
    if(actionPath&&actionPath.row>0){
        _actionContentView.topBorder = self.separatorViewBetweentTextAndActions;
    }else{
        _actionContentView.topBorder = nil;
    }
}
- (void)reloadContentSection0Spacing{
    NSInteger bodySection = 0;
    NSInteger count = [_contentView numberOfItemsInSection:bodySection];
    if(count==0)return;
    UIEdgeInsets groupInnerInsets = UIEdgeInsetsZero;
    if(count==1){
        NSIndexPath *actionIndexPath = [_contentView indexPathForCell:_actionContentView];
        if(actionIndexPath!=nil){//只剩下按钮
            groupInnerInsets = UIEdgeInsetsZero;
        }else{
            CGFloat spacing = [_contentView cellInteritemSpacingForSection:bodySection];
            groupInnerInsets = UIEdgeInsetsMake(spacing, 0, spacing, 0);
        }
    }else{
        CGFloat spacing = [_contentView cellInteritemSpacingForSection:bodySection];
        groupInnerInsets = UIEdgeInsetsMake(spacing, 0, 0, 0);
    }
    [_contentView setGroupInnerInsets:groupInnerInsets forSection:bodySection];
}
- (void)handleAction:(MKUIAlertAction *)action{
    if(self.whenClickAction){
        self.whenClickAction(self, action);
    }
    if(action.handler){
        action.handler(action);
    }
}

#pragma mark - delegate:MKUIListViewDelegate
- (void)listView:(MKUIListView *)listView cancelSelectCell:(UIView *)cell forItemAtIndexPath:(NSIndexPath *)indexPath{
    if(![cell isKindOfClass:MKUIAlertActionView.class])return;
    if (@available(iOS 10.0, *)) {
        UIImpactFeedbackGenerator *impactFeedBack = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleLight];
        [impactFeedBack prepare];
        [impactFeedBack impactOccurred];
    }else{
        //        AudioServicesPlaySystemSound(1519);//普通短震(3D Touch 中 Peek 震动反馈)
        //    AudioServicesPlaySystemSound(1520);//普通短震(3D Touch 中 Pop 震动反馈)
        //    AudioServicesPlaySystemSound(1521);//连续三次短震
    }
}
- (void)listView:(MKUIListView *)listView willDisplayCell:(UIView *)cell forItemAtIndexPath:(NSIndexPath *)indexPath{
    if(cell==self.actionContentView){
        [self.actionContentView mk_autoBounces];
        return;
    }
    if(cell==self.bodyContentView){
        [self.bodyContentView mk_autoBounces];
        return;
    }
}
- (void)listView:(MKUIListView *)listView didSelectCell:(UIView *)cell forItemAtIndexPath:(NSIndexPath *)indexPath{
    if([cell isKindOfClass:MKUIAlertActionView.class]){
        MKUIAlertActionView *actionView = (MKUIAlertActionView *)cell;
        if(!actionView.enableSelection)return;
        //取消弹窗
        [self handleAction:actionView.action];
    }
}
- (CGSize)listView:(MKUIListView *)listView sizeThatFits:(CGSize)size forCell:(UIView *)cell forIndexPath:(NSIndexPath *)indexPath{
    if(listView==self.actionContentView) return [self actionContentView:listView sizeThatFits:size forCell:cell forIndexPath:indexPath];
    if(listView==_contentView) return [self contentView:listView sizeThatFits:size forCell:cell forIndexPath:indexPath];
    return [cell sizeThatFits:size];
}
- (CGSize)actionContentView:(MKUIListView *)listView sizeThatFits:(CGSize)size forCell:(UIView *)cell forIndexPath:(NSIndexPath *)indexPath{
    if(self.actions==0) return CGSizeZero;
    
    CGFloat separatorSize = [listView separatorSizeForSection:indexPath.section];
    
    CGSize s = CGSizeZero;
    if(listView.scrollDirection==MKUIListViewScrollDirectionHorizontal){
        size.width = listView.bounds.size.width;
        s.width = (size.width-separatorSize*(self.actions.count-1))/self.actions.count;
    }else{
        s.width = size.width;
    }
    s.height = self.actionCellHeight;
    return s;
}
- (CGFloat)_contentViewFitHeightWithoutBodyAndAction:(CGSize)size{
    _isSizeFiting = YES;
    CGSize s = [_contentView sizeThatFits:size];
    //sizeThatFits会添加上contentInsets时，但cell的sizeThatFits方法，已经扣除掉这部分值了，所以需要扣除掉contentInsets
    if(s.height>0){
        UIEdgeInsets contentInsets = _contentView.mk_adjustedContentInset;
        s.height -= (contentInsets.top+contentInsets.bottom);
    }
    _isSizeFiting = NO;
    return s.height;
}
- (CGSize)contentView:(MKUIListView *)listView sizeThatFits:(CGSize)size forCell:(UIView *)cell forIndexPath:(NSIndexPath *)indexPath{
    if(indexPath.section==0){//body+button的Section
        if(cell==self.bodyContentView){//bodyContentView:显示title，message等非按钮信息
            if(_isSizeFiting){//用于计算_contentViewFitHeightWithoutBodyAndAction
                return CGSizeZero;
            }
            CGFloat maxHeight = size.height;
            
            UIEdgeInsets groupInsets = [listView groupInsetsForSection:indexPath.section];
            CGSize contentViewSize = CGSizeMake(size.width+groupInsets.left+groupInsets.right, size.height);
            CGFloat contentHeight0 = [self _contentViewFitHeightWithoutBodyAndAction:contentViewSize];
            maxHeight -= contentHeight0;
            
            CGFloat actionContentHeightMin = [self actionContentViewHeightOfMini:size];
            maxHeight -= actionContentHeightMin;
            
            CGSize s = [self.bodyContentView sizeThatFits:size];
            s.height = MAX(MIN(maxHeight,s.height),0);
            s.width = size.width;
            return s;
        }else if(cell==self.actionContentView){
            if(_isSizeFiting){//用于计算_contentViewFitHeightWithoutBodyAndAction
                return CGSizeZero;
            }
            CGSize s = size;
            if(self.actionContentView.scrollDirection==MKUIListViewScrollDirectionHorizontal){
                s.height = self.actionCellHeight;
            }else{
                CGFloat maxHeight = size.height;
                
                UIEdgeInsets groupInsets = [listView groupInsetsForSection:indexPath.section];
                CGSize contentViewSize = CGSizeMake(size.width+groupInsets.left+groupInsets.right, size.height);
                CGFloat contentHeight0 = [self _contentViewFitHeightWithoutBodyAndAction:contentViewSize];
                maxHeight -= contentHeight0;
                
                CGFloat bodyContentHeight = [self.bodyContentView sizeThatFits:size].height;
                maxHeight -= bodyContentHeight;
                
                CGFloat actionContentHeightMin = [self actionContentViewHeightOfMini:size];
                s = [self.actionContentView sizeThatFits:size];
                s.height = MIN(s.height,maxHeight);
                s.height = MAX(s.height,actionContentHeightMin);
            }
            s.width = size.width;
            return s;
        }
    }
    if(indexPath.section==1){//cancelSection
        CGSize s = size;
        s.height = self.actionCellHeight;
        return s;
    }
    return [cell sizeThatFits:size];
}
- (CGFloat)actionContentViewHeightOfMini:(CGSize)size{
    CGFloat minActionCount = self.preferredStyle==MKUIAlertViewStyleAlert?6.5:1.5;
    CGFloat actionContentHeightMin = [self actionContentViewHeightWithCount:MIN(minActionCount,self.actionContentView.numberOfItems)];
    actionContentHeightMin = MIN(actionContentHeightMin,size.height*0.5);
    return actionContentHeightMin;
}
- (CGFloat)actionContentViewHeightWithCount:(CGFloat)count{
    if(count<=0)return 0;
    CGFloat actionCellHeight = self.actionCellHeight;
    if(self.actionContentView.scrollDirection==MKUIListViewScrollDirectionHorizontal){
        return actionCellHeight;
    }else{
        CGFloat separatorSize = [self.actionContentView separatorSizeForSection:0];
        return actionCellHeight*count+MAX(0,(count-1))*separatorSize;
    }
}
- (CGFloat)cancelSectionHeight{
    NSInteger counts = [_contentView numberOfItemsInSection:1];
    if(counts==0)return 0;
    CGFloat actionCellHeight = self.actionCellHeight;
    CGFloat separatorSize = [_contentView separatorSizeForSection:1];
    return actionCellHeight*counts+MAX(0,(counts-1))*separatorSize;
}
- (CGFloat)actionCellHeight{
    return self.preferredStyle==MKUIAlertViewStyleAlert?44:57;
}


#pragma mark - keyboard
- (void)__MKUIAlertView_onKeyboardShow:(NSNotification *)noti{
    if(!self.autoAdjustContentWhenKeyboardChange)return;
    self.keyboardTapGesture.enabled = YES;
}
- (void)__MKUIAlertView_onKeyboardChange:(NSNotification *)noti{
    if(!self.autoAdjustContentWhenKeyboardChange)return;
    self.keyboardChangeNotification = noti;
    [self adjustContentWithUIKeyboardChangeNotification:noti];
}
- (void)__MKUIAlertView_onKeyboardHide:(NSNotification *)noti{
    self.keyboardChangeNotification = nil;
    if(!self.autoAdjustContentWhenKeyboardChange)return;
    self.keyboardTapGesture.enabled = NO;
}
- (void)__MKUIAlertView_onKeyboardTap:(id)sender{
    if(!self.autoAdjustContentWhenKeyboardChange)return;
    [self endEditing:YES];
}
- (void)adjustContentWithUIKeyboardChangeNotification:(NSNotification *)noti{
    [self adjustContentWithUIKeyboardChangeNotification:noti responderViewClass:self.autoAdjustViewClassWhenKeyboardChange.class];
}
- (void)adjustContentWithUIKeyboardChangeNotification:(NSNotification *)noti responderViewClass:(Class)responderViewClass{
    if(!self.superview)return;
    if(!noti){
        self.transform = CGAffineTransformIdentity;
        return;
    }
    CGFloat duration = [noti.userInfo mk_floatForKeyPath:UIKeyboardAnimationDurationUserInfoKey];
    CGRect keyboardFrame = [noti.userInfo mk_NSValueForKeyPath:UIKeyboardFrameEndUserInfoKey].CGRectValue;
    UIWindow *window = [self mk_firstSuperViewWithClass:UIWindow.class];
    UIView *responderView = self.mk_firstResponder;
    if(responderViewClass!=nil){
        UIView *superView = [responderView mk_firstSuperViewWithClass:responderViewClass];
        if(superView){
            responderView = superView;
        }
    }
    CGAffineTransform m1 = CGAffineTransformIdentity;
    if(responderView){
        CGRect responderFrame = [responderView.superview convertRect:responderView.mk_frameSafety toView:window];
        if(keyboardFrame.size.height!=0){
            CGRect maxFrame = responderFrame;
            MKCGRectSetMaxY(&maxFrame, keyboardFrame.origin.y);
            if(responderFrame.origin.y>maxFrame.origin.y){
                m1 = CGAffineTransformConcat(m1, CGAffineTransformMakeTranslation(0, -(responderFrame.origin.y-maxFrame.origin.y)));
            }
        }
    }
    [UIView animateWithDuration:duration animations:^{
        self.transform = m1;
    }];
}
- (void)__onMaskViewDidTap:(id)sender{
    if(self.preferredStyle!=MKUIAlertViewStyleActionSheet) return;
    if(!self.showMaskView)return;
    for(MKUIAlertAction *action in self.actions){
        if(action.style==MKUIAlertActionStyleCancel&&action.isEnabled){
            [self handleAction:action];
            return;
        }
    }
}

#pragma mark - layout
- (void)layoutMaskViewInContainerView:(UIView *)container{
    CGRect bounds = container.bounds;
    if(self.showMaskView){
        self.maskView.frame = bounds;
    }else{
        self.maskView.frame = self.mk_frameSafety;
    }
}
- (void)_layoutSelfInContainerView:(UIView *)container{
    [self layoutSelfInContainerView:container];
    if(self.autoAdjustContentWhenKeyboardChange&&self.keyboardChangeNotification){
        [self adjustContentWithUIKeyboardChangeNotification:self.keyboardChangeNotification];
    }
}
- (void)layoutSelfInContainerView:(UIView *)container{
    CGRect fullBounds = container.bounds;
    //
    UIEdgeInsets safeAreaInsets = UIEdgeInsetsZero;
    if (@available(iOS 11.0, *)) {
        safeAreaInsets = container.safeAreaInsets;
    }
    safeAreaInsets.bottom = MAX(safeAreaInsets.bottom,8);//非刘海屏时，要与下部有8的间隔
    
    if(self.preferredStyle==MKUIAlertViewStyleActionSheet){
        //将safeAreaInsets.bottom转移至contentView.contentInset.bottom
        _contentView.contentInset = UIEdgeInsetsMake(0, 0, safeAreaInsets.bottom, 0);
        safeAreaInsets.bottom = 0;
    }else{
        _contentView.contentInset = UIEdgeInsetsZero;
    }
    CGRect bounds = UIEdgeInsetsInsetRect(fullBounds, safeAreaInsets);
    CGRect f1 = bounds;
    f1.size = [self sizeThatFits:bounds.size];
    
    //横竖屏时区分对待最大高度值
    BOOL hor = fullBounds.size.width>fullBounds.size.height;
    CGFloat minPadding = 20;
    if(hor){
        if(self.preferredStyle==MKUIAlertViewStyleActionSheet){
            f1.size.height = MIN(f1.size.height,bounds.size.height-minPadding);
        }else{
            f1.size.height = MIN(f1.size.height,bounds.size.height-minPadding);
        }
    }else{
        f1.size.height = MIN(f1.size.height,bounds.size.height-44-minPadding);//扣掉navBar的44高度
    }
    
    if(self.preferredStyle==MKUIAlertViewStyleActionSheet){
        MKCGRectAlignMidXToRect(&f1, fullBounds);
        MKCGRectAlignMaxYToRect(&f1, fullBounds);//对齐最外层的底
    }else{
        MKCGRectAlignMidXToRect(&f1, fullBounds);
        MKCGRectAlignMidYToRect(&f1, fullBounds);
    }
    self.mk_frameSafety = f1;
}
- (void)presentToView:(UIView *)container animated:(BOOL)animated completion:(void(^ _Nullable)(BOOL finished))completion{
    if(!container){
        if(completion){
            completion(YES);
        }
        return;
    };
    if(self.autoAdjustContentWhenKeyboardChange){
        [self.maskView addGestureRecognizer:self.keyboardTapGesture];
    }
    if(!self.whenClickAction){
        self.whenClickAction = ^(MKUIAlertView * _Nonnull alertView, MKUIAlertAction * _Nonnull action) {
            if(!action.shouldDismissWhenActionHandle) return;
            [alertView dismissFromSuperViewWithAnimated:YES completion:nil];
        };
    }
    CGRect bounds = container.bounds;
    [container addSubview:self.maskView];
    [self layoutMaskViewInContainerView:container];
    
    [container addSubview:self];
    self.maskView.alpha = self.showMaskView?1:0;
    [self _layoutSelfInContainerView:container];
    if(animated){
        CGAffineTransform m = CGAffineTransformIdentity;
        if(self.preferredStyle==MKUIAlertViewStyleAlert){
            self.alpha = 0;
            m = CGAffineTransformConcat(m, CGAffineTransformMakeScale(1.2, 1.2));
        }else{
            CGRect f1 = self.mk_frameSafety;
            m = CGAffineTransformConcat(m, CGAffineTransformMakeTranslation(0, bounds.size.height-f1.origin.y));
        }
        self.maskView.alpha = 0;
        self.transform = m;
        [UIView animateWithDuration:0.25 animations:^{
            if(self.preferredStyle==MKUIAlertViewStyleAlert){
                self.alpha = 1;
            }
            self.maskView.alpha = self.showMaskView?1:0;
            self.transform = CGAffineTransformIdentity;
        } completion:^(BOOL finished) {
            if(completion){
                completion(finished);
            }
        }];
    }else{
        if(completion){
            completion(YES);
        }
    }
}
- (void)dismissFromSuperViewWithAnimated:(BOOL)animated completion:(void(^ _Nullable)(BOOL finished))completion{
    if(!self.superview){
        if(completion){
            completion(YES);
        }
        return;
    }
    [self.keyboardTapGesture.view removeGestureRecognizer:self.keyboardTapGesture];
    if(animated){
        CGAffineTransform m = CGAffineTransformIdentity;
        if(self.preferredStyle==MKUIAlertViewStyleActionSheet){
            CGRect bounds = self.superview.bounds;
            CGRect f1 = self.mk_frameSafety;
            m = CGAffineTransformConcat(m, CGAffineTransformMakeTranslation(0, bounds.size.height-f1.origin.y));
        }
        [UIView animateWithDuration:0.2 animations:^{
            if(self.maskView.superview){
                self.maskView.alpha = 0;
            }
            if(self.preferredStyle==MKUIAlertViewStyleActionSheet){
                self.transform = m;
            }else{
                self.alpha = 0;
            }
        } completion:^(BOOL finished) {
            [self.maskView removeFromSuperview];
            [self removeFromSuperview];
            self.maskView.alpha = 1;
            self.alpha = 1;
            self.transform = CGAffineTransformIdentity;
            if(completion){
                completion(finished);
            }
        }];
    }else{
        [self removeFromSuperview];
        [self.maskView removeFromSuperview];
        if(completion){
            completion(YES);
        }
    }
}
@end

@implementation UIView (MKUIAlertView)
- (void)mk_presentAlertView:(nullable MKUIAlertView *)alertView animated:(BOOL)animated completion:(void(^ _Nullable)(BOOL finished))completion{
    MKUIAlertView *oldAlertView = [self mk_alertView];
    if(oldAlertView==alertView){
        if(completion){
            completion(YES);
        }
        return;
    }
    if(oldAlertView){
        if(!alertView){
            [self mk_dismissAlertView:oldAlertView animated:animated completion:completion];
        }else{
            //取消旧的alert，弹出新的alert
            [self mk_dismissAlertView:oldAlertView animated:animated completion:^(BOOL finished) {
                [alertView presentToView:self animated:animated completion:completion];
            }];
        }
    }else{
        [alertView presentToView:self animated:animated completion:completion];
    }
}
- (void)mk_dismissAlertView:(nullable MKUIAlertView *)alertView animated:(BOOL)animated completion:(void(^ _Nullable)(BOOL finished))completion{
    if(alertView.superview!=self){
        if(completion){
            completion(YES);
        }
        return;
    }
    [alertView dismissFromSuperViewWithAnimated:animated completion:completion];
}
- (MKUIAlertView *)mk_alertView{
    for(UIView *subview in self.subviews){
        if([subview isKindOfClass:MKUIAlertView.class]){
            return (MKUIAlertView *)subview;
        }
    }
    return nil;
}
@end

@interface MKUIAlertViewTextCellView()
@property(nonatomic,strong) UILabel *textLabel;
@end
@implementation MKUIAlertViewTextCellView
#ifdef DEBUG_MKUIAlertView
- (void)dealloc{
    NSLog(@"dealloc:MKUIAlertViewTextCellView:%@",self);
}
#endif
- (id)initWithFrame:(CGRect)frame{
    if(self=[super initWithFrame:frame]){
        self.backgroundColor = UIColor.clearColor;
        self.textLabel = [[UILabel alloc] init];
        self.textLabel.numberOfLines = 0;
        self.textLabel.textAlignment = NSTextAlignmentCenter;
        [self.contentView addSubview:self.textLabel];
    }
    return self;
}
- (void)setText:(NSString *)text{
    if(_text==text||[_text isEqualToString:text])return;
    _text = text;
    self.textLabel.text = text;
}
- (void)layoutContentView{
    [super layoutContentView];
    CGRect contentBounds = self.contentView.bounds;
    CGRect bounds = UIEdgeInsetsInsetRect(contentBounds, self.contentInsets);
    CGRect f1 = bounds;
    f1.size = [self.textLabel sizeThatFits:bounds.size];
    MKCGRectAlignMidXToRect(&f1, bounds);
    MKCGRectAlignMidYToRect(&f1, bounds);
    self.textLabel.frame = f1;
}
- (CGSize)sizeThatFits:(CGSize)size{
    CGSize size1 = size;
    UIEdgeInsets insets = self.contentInsets;
    size1.width -= insets.left+insets.right;
    size1.height -= insets.top+insets.bottom;
    CGSize s = [self.textLabel sizeThatFits:CGSizeMake(size1.width, 9999999)];
    if(s.height>0){
        s.height += insets.top+insets.bottom;
        s.width += insets.left+insets.right;
    }
    return s;
}
@end

@interface MKUIAlertController()<UIViewControllerTransitioningDelegate,UIViewControllerAnimatedTransitioning>{
    MKUIAlertView *_alertView;
}
@property(nonatomic,assign) BOOL animationForDismissed;
@property(nonatomic,copy,nullable) void(^whenDismissed)(MKUIAlertController *alertController);
@end
@implementation MKUIAlertController
#ifdef DEBUG_MKUIAlertView
- (void)dealloc{
    NSLog(@"dealloc:MKUIAlertController:%@",self);
}
#endif
- (id)init{
    if(self=[super init]){
        self.transitioningDelegate = self;
        self.modalPresentationStyle = UIModalPresentationOverFullScreen;
    }
    return self;
}

+ (instancetype)alertControllerWithTitle:(nullable NSString *)title message:(nullable NSString *)message preferredStyle:(MKUIAlertViewStyle)preferredStyle{
    MKUIAlertView *alertView = [MKUIAlertView alertViewWithTitle:title message:message preferredStyle:preferredStyle];
    MKUIAlertController *vc = [[self alloc] init];
    vc.alertView = alertView;
    return vc;
}
+ (instancetype)alertControllerWithAlertView:(MKUIAlertView *)alertView{
    MKUIAlertController *vc = [[self alloc] init];
    vc.alertView = alertView;
    return vc;
}
- (void)viewDidLoad{
    [super viewDidLoad];
}
- (void)setAlertView:(MKUIAlertView *)alertView{
    if(_alertView==alertView)return;
    if(_alertView){
        [_alertView dismissFromSuperViewWithAnimated:NO completion:nil];
    }
    _alertView = alertView;
    if(!_alertView)return;
    
    @MK_WEAKIFY(self);
    _alertView.whenClickAction = ^(MKUIAlertView *alertView, MKUIAlertAction *action) {
        @MK_NORMALIZE(self);
        if(!action.shouldDismissWhenActionHandle) return;
        [self dismissViewControllerAnimated:YES completion:nil];
    };
    if(!_alertView.superview){
        [_alertView presentToView:self.view animated:NO completion:nil];
        [self setNeedReloadData];
    }
}
- (MKUIAlertView *)alertView{
    if(_alertView)return _alertView;
    self.alertView = [[MKUIAlertView alloc] init];
    return _alertView;
}
- (void)setAlertView:(MKUIAlertView *)alertView animated:(BOOL)animated completion:(void(^)(BOOL finished))completion{
    MKUIAlertView *oldAlertView = _alertView;
    if(oldAlertView==alertView){
        if(completion){
            completion(YES);
        }
        return;
    }
    if(oldAlertView){
        if(!alertView){
            [oldAlertView dismissFromSuperViewWithAnimated:animated completion:completion];
        }else{
            //取消旧的alert，弹出新的alert
            [oldAlertView dismissFromSuperViewWithAnimated:animated completion:^(BOOL finished) {
                [alertView presentToView:self.view animated:animated completion:^(BOOL finished) {
                    self.alertView = alertView;
                    if(completion){
                        completion(finished);
                    }
                }];
            }];
        }
    }else{
        [alertView presentToView:self.view animated:animated completion:^(BOOL finished) {
            self.alertView = alertView;
            if(completion){
                completion(finished);
            }
        }];
    }
}
- (void)setPreferredStyle:(MKUIAlertViewStyle)preferredStyle{
    if(self.preferredStyle==preferredStyle)return;
    self.alertView.preferredStyle = preferredStyle;
    [self setNeedReloadData];
}
- (MKUIAlertViewStyle)preferredStyle{
    return self.alertView.preferredStyle;
}
- (void)setTitle:(NSString *)title{
    if(self.title==title||[self.title isEqualToString:title])return;
    self.alertView.title = title;
    [self setNeedReloadData];
}
- (NSString *)title{
    return self.alertView.title;
}
- (void)setMessage:(NSString *)message{
    if(self.message==message||[self.message isEqualToString:message])return;
    self.alertView.message = message;
    [self setNeedReloadData];
}
- (NSString *)message{
    return self.alertView.message;
}
- (void)addAction:(MKUIAlertAction *)action{
    [self.alertView addAction:action];
    [self setNeedReloadData];
}
- (void)setActions:(NSArray<MKUIAlertAction *> *)actions{
    self.alertView.actions = actions;
    [self setNeedReloadData];
}
- (NSArray<MKUIAlertAction *> *)actions{
    return self.alertView.actions;
}
- (void)reloadData{
    [self.alertView reloadData];
    [self.view setNeedsLayout];
    [self.view layoutIfNeeded];
}
- (void)setNeedReloadData{
    [self.alertView setNeedReloadData];
    [self.view setNeedsLayout];
}
- (void)reloadDataIfNeeded{
    [self.alertView reloadDataIfNeeded];
    [self.view layoutIfNeeded];
}
- (void)presentInWindow:(UIWindow *)window animated:(BOOL)animated completion:(void (^ __nullable)(void))completion;{
    if(window.rootViewController){
        //此时rootViewController还未加载，延时显示
        dispatch_async(dispatch_get_main_queue(), ^{
            [[MKUIAlertTaskManager sharedInstance] presentAlertController:self inWindow:window animated:animated completion:completion];
        });
        return;
    }
    [[MKUIAlertTaskManager sharedInstance] presentAlertController:self inWindow:window animated:animated completion:completion];
}
- (void)presentInSharedWindowWithAnimated:(BOOL)animated completion:(void (^ __nullable)(void))completion{
    UIWindow *window = UIWindow.mkui_sharedAlertWindow;
    [self presentInWindow:window animated:animated completion:completion];
}
- (void)dismissFromWindowWithAnimated:(BOOL)animated completion:(void (^ __nullable)(void))completion{
    if(self.presentingViewController){
        [self dismissViewControllerAnimated:animated completion:completion];
    }else{
        //从task任务队列中移除
        [[MKUIAlertTaskManager sharedInstance] removeTask:self];
        if(completion){
            completion();
        }
    }
}
- (void)show{
    [self presentInSharedWindowWithAnimated:YES completion:nil];
}
- (void)hide{
    [self dismissFromWindowWithAnimated:YES completion:nil];
}
//自定义过场动画
#pragma mark - delegate:UIViewControllerTransitioningDelegate
- (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source{
    self.animationForDismissed = NO;
    return self;
}
//
- (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed{
    self.animationForDismissed = YES;
    return self;
}
#pragma mark - delegate:UIViewControllerAnimatedTransitioning
- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext{
    return self.animationForDismissed?0.2:0.25;
}
// This method can only be a no-op if the transition is interactive and not a percentDriven interactive transition.
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext{
    if(self.animationForDismissed){
        [self animateTransitionForDismissed:transitionContext];
    }else{
        [self animateTransitionForPresented:transitionContext];
    }
}
- (void)animateTransitionForPresented:(id <UIViewControllerContextTransitioning>)transitionContext{
    UIView *view = [transitionContext viewForKey:UITransitionContextToViewKey];
    [transitionContext.containerView addSubview:view];
    [self.alertView presentToView:view animated:YES completion:^(BOOL finished) {
        BOOL cancle = [transitionContext transitionWasCancelled];
        [transitionContext completeTransition:!cancle];
    }];
}
- (void)animateTransitionForDismissed:(id <UIViewControllerContextTransitioning>)transitionContext{
    @MK_WEAKIFY(self);
    [self.alertView dismissFromSuperViewWithAnimated:YES completion:^(BOOL finished) {
        @MK_NORMALIZE(self);
        BOOL cancle = [transitionContext transitionWasCancelled];
        [transitionContext completeTransition:!cancle];
        if(self.whenDismissed){
            self.whenDismissed(self);
        }
    }];
}
@end


@interface _MKUIAlertWindowTask : NSObject
@property(nonatomic,weak) UIViewController *viewController;
@property(nonatomic,weak) UIWindow *window;
@property(nonatomic,strong) MKUIAlertController *alert;
@property(nonatomic,assign) BOOL animated;
@property(nonatomic,copy,nullable) void (^completion)(void);
- (void)doAlert;
@end
@implementation _MKUIAlertWindowTask
- (void)doAlert{
    [self.viewController presentViewController:self.alert animated:self.animated completion:self.completion];
}
@end

@interface MKUIAlertTaskManager()
@property(nonatomic,strong) NSMutableArray<_MKUIAlertWindowTask *> *tasks;//任务列表
@property(nonatomic,strong,nullable) _MKUIAlertWindowTask *currentTask;
@end
@implementation MKUIAlertTaskManager
MKDEF_SINGLETON(MKUIAlertTaskManager)
- (id)init{
    if(self=[super init]){
        self.tasks = [[NSMutableArray alloc] init];
    }
    return self;
}
- (void)presentAlertController:(MKUIAlertController *)alert inWindow:(UIWindow *)window animated:(BOOL)animated completion:(void (^ __nullable)(void))completion{
    _MKUIAlertWindowTask *task = [[_MKUIAlertWindowTask alloc] init];
    task.alert = alert;
    task.viewController = window.rootViewController;
    task.window = window;
    task.animated = animated;
    task.completion = completion;
    alert.whenDismissed = ^(MKUIAlertController *alertController) {
        [[MKUIAlertTaskManager sharedInstance] _popTask];
    };
    [self.tasks addObject:task];
    if(self.currentTask==nil){
        [self _popTask];
    }
}
- (void)removeTask:(MKUIAlertController *)alert{
    NSInteger index = NSNotFound;
    for(int i=0;i<self.tasks.count;i++){
        _MKUIAlertWindowTask *task = self.tasks[i];
        if(task.alert==alert){
            index = i;
            continue;
        }
    }
    if(index!=NSNotFound){
        [self.tasks removeObjectAtIndex:index];
    }
}
- (void)_popTask{
    if(self.currentTask){
        if(self.currentTask.window==UIWindow.mkui_sharedAlertWindow){
            self.currentTask.window.hidden = YES;
        }
    }
    self.currentTask = nil;
    if(self.tasks.count==0)return;
    _MKUIAlertWindowTask *task = self.tasks.firstObject;
    [self.tasks removeObjectAtIndex:0];
    if(task.viewController==nil){
        [self _popTask];
        return;
    }
    self.currentTask = task;
    if(self.currentTask.window==UIWindow.mkui_sharedAlertWindow){
        self.currentTask.window.hidden = NO;
    }
    [task doAlert];
}
@end
@implementation UIWindow(MKUIAlertController)
/// 用于显示MKUIAlertController弹窗的窗口
+ (instancetype)mkui_sharedAlertWindow{
    static dispatch_once_t once;
    static id __singleton__;
    dispatch_once( &once, ^{
        UIWindow *window = [[self alloc] init];
        window.rootViewController = [[UIViewController alloc] init];
        window.backgroundColor = window.rootViewController.view.backgroundColor = UIColor.clearColor;
        window.hidden = YES;
        window.windowLevel = UIWindowLevelAlert;
        __singleton__ = window;
    } );
    return __singleton__;
}
@end
